package com.gaogzhen.designPattern.producerConsumer;

import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

/**
 * 消息队列
 */
@Slf4j(topic = "c.MessageQueue")
public class MessageQueue {
    /** 消息容器 */
    LinkedList<Message> queue = new LinkedList<>();
    /** 队列容量 */
    private int capacity;

    public MessageQueue(int capacity) {
        this.capacity = capacity;
    }

    /**
     * 获取消息
     * @return  消息
     */
    public Message getMessage() {
        synchronized (queue) {
            // 检查消息队列是否为空
            while (queue.size() == 0) {
                // 消息队列为空不能获取消息，生产者线程等待
                try {
                    log.debug("消息队列为空，线程-{}等待",Thread.currentThread().getName());
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            Message message = queue.removeFirst();
            log.debug("线程-{}消费了消息:{}", Thread.currentThread().getName(), message);
            // 通知生产者可以添加消息
            queue.notifyAll();
            return message;
        }
    }

    /**
     * 添加消息
     * @param message
     */
    public void putMessage(Message message) {
        synchronized (queue) {
            // 检查消息队列是否已满
            while (queue.size() == capacity) {
                // 如果消息队列已满，生产者线程等待
                try {
                    log.debug("消息队列已满，线程-{}等待",Thread.currentThread().getName());
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            queue.addLast(message);
            log.debug("线程-{}生产了消息:{}", Thread.currentThread().getName(), message);
            // 通知消费者可以获取消息
            queue.notifyAll();
        }
    }
}
